package top.hesisi.springboot3.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import top.hesisi.springboot3.aop.AuthInfo;
import top.hesisi.springboot3.service.RedisService;
import top.hesisi.springboot3.util.IpUtils;

import java.lang.annotation.Annotation;

@Slf4j
@Component
@RequiredArgsConstructor
public class AppInterceptor implements HandlerInterceptor {
    private final RedisService redisService;
    // 保存登录认证信息的线程线程，可以确保每一个请求的对象保持隔离
    private static final ThreadLocal<AuthInfo> authInfoThreadLocal = new ThreadLocal<>();

    public static AuthInfo getAuthInfo() {
        return authInfoThreadLocal.get();
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 放置认证信息到线程线程中，方便其他地方获取
        AuthInfo authInfo = new AuthInfo();
        authInfoThreadLocal.set(authInfo);

        //请求中的认证信息
        String token = request.getHeader("Authorization");
        authInfo.setToken(token);

        //获取token对应的用户id
        if (StringUtils.hasText(token)) {
            authInfo.setUid(redisService.load(token,Integer.class));
        }

        //获取客户端的ip地址信息
        String ip = IpUtils.getIpAddr(request);
        //获取请求路径信息
        String url = request.getRequestURI();
        String method = request.getMethod();
        authInfo.setId(ip);
        authInfo.setUrl(url);
        authInfo.setMethod(method);
        log.info("{}访问了{}", ip, url,  method);
        //判断是否访问是控制器
        if (handler instanceof HandlerMethod hm) {
            log.debug("访问控制器：{}", hm.getBeanType().getSimpleName());
            RequestMapping annotation = hm.getBeanType().getAnnotation(RequestMapping.class);
            String controller = "";
            if (annotation != null && annotation.value().length > 0) {
                controller = annotation.value()[0];
            }
            annotation = hm.getMethodAnnotation(RequestMapping.class);
            if (annotation != null && annotation.value().length > 0) {
                controller  += annotation.value()[0];
            }
            log.debug("控制器请求的注解：{}", controller);
            authInfo.setMapping(controller);
            log.debug("认证信息：{}", authInfo);

        }
        return true;
    }
}
